package com.mingqijia.gassafety.webserver.service.impl;
import java.util.Date;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.db.entity.*;
import com.mingqijia.gassafety.db.mapper.MaintainlogMapper;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.PageColumnConst;
import com.mingqijia.gassafety.shared.constant.PageListCode;
import com.mingqijia.gassafety.shared.constant.TemplateTypeEnum;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.utils.HeaderUtil;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageColumns;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageUtil;
import com.mingqijia.gassafety.webserver.request.MaintainLogAddRequest;
import com.mingqijia.gassafety.webserver.request.MaintainLogRequest;
import com.mingqijia.gassafety.webserver.response.CompanyResponse;
import com.mingqijia.gassafety.webserver.response.FieldListShowResponse;
import com.mingqijia.gassafety.webserver.response.MaintainLogResponse;
import com.mingqijia.gassafety.webserver.response.WarningDataResponse;
import com.mingqijia.gassafety.webserver.service.*;
import com.mingqijia.gassafety.webserver.service.workorder.DtuBindingOrderService;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.mingqijia.gassafety.shared.constant.Constants.ORG_MAP_SUBSCODE;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wanghai
 * @since 2022-03-10
 */
@Service
@Slf4j
public class MaintainlogServiceImpl extends ServiceImpl<MaintainlogMapper, Maintainlog> implements MaintainlogService {

    @Autowired
    MaintainlogMapper maintainlogMapper;
    @Autowired
    ConsumerService consumerService;
    @Autowired
    UserService userService;
    @Autowired
    DepartmentService departmentService;
    @Autowired
    ConfigureHolder holder;
    @Autowired
    DtuBindingOrderService dtuBindingOrderService;
    @Autowired
    EquipmentService equipmentService;
    @Autowired
    HeaderUtil headerUtil;
    @Autowired
    CommonService commonService;

    @Autowired
    FieldListShowService fieldListShowService;
    @Autowired
    CompanyService companyService;
    @Autowired
    UserPermissionService userPermissionService;

    @Override
    public PageUtil<MaintainLogResponse> maintainList(MaintainLogRequest req) {
        List<MaintainLogResponse> resultList = new ArrayList<>();
        String spId = ApplicationUtils.getWorkingSpId();

        req.setTemplateType(headerUtil.getTemplateType());
        //根据spId换path
        String path = departmentService.getPath(spId);
        List<FieldListShowResponse> responses = fieldListShowService.queryListShowByShowStatus(PageListCode.MAINTAIN_RECORD.getCode(), spId);
        List<String> fields = responses.stream().map(FieldListShowResponse::getFieldCode).collect(Collectors.toList());
        List<String> titles = responses.stream().map(FieldListShowResponse::getFieldName).collect(Collectors.toList());
        //页面字段模板
        List<PageColumns> pageColumns = new ArrayList<>();
        if(TemplateTypeEnum.TEMPLATE_TYPE_1.getCode() == req.getTemplateType()){
            pageColumns = PageColumnConst.add(titles.toArray(new String[]{}), fields.toArray(new String[]{}));
            return getWithType1(req, resultList, spId, pageColumns, path);
        }

            pageColumns = PageColumnConst.add(PageColumnConst.MaintainVccUserTitles, PageColumnConst.MaintainVccUserIndices);
            return getWithType2(req, resultList, spId, pageColumns, path);
    }

    private PageUtil<MaintainLogResponse> getWithType2(MaintainLogRequest req, List<MaintainLogResponse> resultList, String spId, List<PageColumns> pageColumns, String path) {

        //1、查询条件过滤出用户IDs
        List<Integer> consumerIds = new ArrayList<>();
        if (!StringUtils.isEmpty(req.getMemberId()) || !StringUtils.isEmpty(req.getContactName()) ||
                !StringUtils.isEmpty(req.getContactPhone())||!StringUtils.isEmpty(req.getInstallationAddress()) ||
                !StringUtils.isEmpty(req.getIndustryType())) {
            LambdaQueryWrapper<DtuBindingOrder> queryWrapper = new LambdaQueryWrapper();
            if (!StringUtils.isEmpty(req.getContactName())) {
                queryWrapper.like(DtuBindingOrder::getCustName, req.getContactName());
            }
            if (!StringUtils.isEmpty(req.getContactPhone())) {
                queryWrapper.like(DtuBindingOrder::getPhone, req.getContactPhone());
            }
            if (!StringUtils.isEmpty(req.getMemberId())) {
                queryWrapper.like(DtuBindingOrder::getMemberId, req.getMemberId());
            }
            queryWrapper.eq(DtuBindingOrder::getSpId, spId);
            consumerIds = dtuBindingOrderService.list(queryWrapper).stream()
                    .map(DtuBindingOrder::getConsumerId).collect(Collectors.toList());
            //紫荆设备客户
            LambdaQueryWrapper<Consumer> lqw = new LambdaQueryWrapper();
            lqw.eq(!StringUtils.isEmpty(req.getMemberId()), Consumer::getMemberId, req.getMemberId())
                    .eq(!StringUtils.isEmpty(req.getContactPhone()), Consumer::getPhone, req.getContactPhone());
            List<Integer> consumers = consumerService.list(lqw).stream().map(Consumer::getId).collect(Collectors.toList());

            consumerIds.addAll(consumers);

            LambdaQueryWrapper<Dtu> dtuQueryWrapper = new LambdaQueryWrapper<>();
            dtuQueryWrapper.eq(!StringUtils.isEmpty(req.getInstallationAddress()), Dtu::getInstallationAddress,
                    req.getInstallationAddress()).in(Dtu::getConsumerId, consumerIds);
            consumerIds = equipmentService.list(dtuQueryWrapper).stream().map(Dtu::getConsumerId).
                    collect(Collectors.toList());

            LambdaQueryWrapper<Consumer> consumerQueryWrapper = new LambdaQueryWrapper<>();
            consumerQueryWrapper.eq(!StringUtils.isEmpty(req.getIndustryType()), Consumer::getIndustryType, req.getIndustryType())
                    .in(Consumer::getId, consumerIds);
            consumerIds = consumerService.list(consumerQueryWrapper).stream().map(Consumer::getId).collect(Collectors.toList());

            if (consumerIds.isEmpty()) {
                return new PageUtil(req.getPage(), req.getPageSize(), 0, resultList, pageColumns);
            }
        }

        //2、根据条件查询维保记录表
        LambdaQueryWrapper<Maintainlog> queryWrapper = new LambdaQueryWrapper();
        if (!consumerIds.isEmpty()) {
            queryWrapper.in(Maintainlog::getConsumerId,consumerIds);
        }
        if (!StringUtils.isEmpty(req.getTimeStart())) {
            queryWrapper.ge(Maintainlog::getTime, req.getTimeStart());
        }
        if (!StringUtils.isEmpty(req.getTimeEnd())) {
            queryWrapper.le(Maintainlog::getTime, req.getTimeEnd());
        }
        if (!StringUtils.isEmpty(req.getUserName())) {
            queryWrapper.like(Maintainlog::getPersonName, req.getUserName());
        }
        queryWrapper.eq(!StringUtils.isEmpty(path), Maintainlog::getPath, path).orderByDesc(Maintainlog::getTime);
        //数据权限
        List<Integer> permissionConsumerIds = userPermissionService.getDepartConsumerIds(spId, ApplicationUtils.getUserId());
        if( null!=permissionConsumerIds && !permissionConsumerIds.isEmpty()){
            queryWrapper.in(Maintainlog::getConsumerId,permissionConsumerIds);
        }

        Page pageHelper = PageHelper.startPage(req.getPage(), req.getPageSize());
        List<Maintainlog> list = maintainlogMapper.selectList(queryWrapper);

        if (!list.isEmpty()) {
            //查询所属部门
            LambdaQueryWrapper<Department> departmentWrapper = new LambdaQueryWrapper();
            departmentWrapper.in(Department::getId, list.stream().map(Maintainlog::getDepartmentId).collect(Collectors.toList()));
            List<Department> departmentList = departmentService.list(departmentWrapper);
            Map<Integer, Department> departmentMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(departmentList)) {
                departmentMap = departmentList.stream().collect(Collectors.toMap(Department::getId, Department -> Department, (a1, a2) -> a1));
            }
            //查询客户信息
            LambdaQueryWrapper<Consumer> consumerQueryWrapper = new LambdaQueryWrapper<>();
            consumerQueryWrapper.eq(Consumer::getSpId, spId)
                    .in(Consumer::getId, list.stream().map(Maintainlog::getConsumerId).collect(Collectors.toList()));
            List<Consumer> consumerList = consumerService.list(consumerQueryWrapper);
            Map<Integer, Consumer> consumerMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(consumerList)) {
                consumerMap = consumerList.stream().collect(Collectors.toMap(Consumer::getId, Consumer -> Consumer, (a1, a2) -> a1));
            }
            //查询安装地址
            LambdaQueryWrapper<Dtu> dtuQueryWrapper = new LambdaQueryWrapper<>();
            dtuQueryWrapper.eq(Dtu::getSpId, spId)
                   .in(Dtu::getConsumerId, list.stream().map(Maintainlog::getConsumerId).collect(Collectors.toList()));
            List<Dtu> dtuList = equipmentService.list(dtuQueryWrapper);
            Map<Integer, String> dtuMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(dtuList)) {
                dtuMap = dtuList.stream().collect(Collectors.toMap(Dtu::getConsumerId, Dtu::getInstallationAddress, (a1, a2) -> a1));
            }
            //查询联系人信息
            LambdaQueryWrapper<DtuBindingOrder> contactsQueryWrapper = new LambdaQueryWrapper<>();
            contactsQueryWrapper.eq(DtuBindingOrder::getSpId, spId).in(DtuBindingOrder::getConsumerId, list.stream().map(Maintainlog::getConsumerId).collect(Collectors.toList()));
            List<DtuBindingOrder> bindings = dtuBindingOrderService.list(contactsQueryWrapper);
            Map<Integer, DtuBindingOrder> bindingOrderMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(bindings)) {
                bindingOrderMap = bindings.stream().collect(Collectors.toMap(DtuBindingOrder::getConsumerId, DtuBindingOrder -> DtuBindingOrder, (a1, a2) -> a1));
            }
            List<DictionaryItemRespDTO> industryTypeCodeList = holder.getDictionaryByKey(Constants.INDUSTRY_TYPE_CODE);
            //查询
            for (Maintainlog maintainlog : list) {
                MaintainLogResponse res = new MaintainLogResponse();
                BeanUtils.copyProperties(maintainlog, res);
                //填写人
                res.setUserName(maintainlog.getPersonName());
                if (departmentMap.containsKey(maintainlog.getDepartmentId())) {
                    Department department = departmentMap.get(maintainlog.getDepartmentId());
                    res.setDepartment(department.getName());
                }
                if (consumerMap.containsKey(res.getConsumerId())) {
                    Consumer consumer = consumerMap.get(res.getConsumerId());
                    res.setCustPhone(consumer.getPhone());
                    res.setMemberId(consumer.getMemberId());
                    res.setIndustryType(consumer.getIndustryType());
                    //行业类型
                    if (!StringUtils.isEmpty(res.getIndustryType())) {
                        DictionaryItemRespDTO communicationModeDict = industryTypeCodeList.stream().filter(a->a.getValue().equals(
                                res.getIndustryType())).collect(Collectors.toList()).get(0);
                        res.setIndustryTypeName(communicationModeDict.getName());
                    }
                }
                //安装地址
                if(dtuMap.containsKey(res.getConsumerId())){
                    res.setInstallationAddress(dtuMap.get(res.getConsumerId()));
                }
                if(bindingOrderMap.containsKey(res.getConsumerId())){
                    DtuBindingOrder dtuBindingOrder = bindingOrderMap.get(res.getConsumerId());
                    res.setContactName(dtuBindingOrder.getCustName());
                    res.setContactPhone(dtuBindingOrder.getPhone());
                }
                res.setLatestTime(maintainlog.getTime());
                res.setId(maintainlog.getId().longValue());
                resultList.add(res);
            }
        }

        return  new PageUtil(req.getPage(), req.getPageSize(), pageHelper.getTotal(), resultList, pageColumns);
    }

    @NotNull
    private PageUtil getWithType1(MaintainLogRequest req, List<MaintainLogResponse> resultList, String spId, List<PageColumns> pageColumns, String path) {
        List<Integer> consumerIds = new ArrayList<>();
        if (!StringUtils.isEmpty(req.getSubsCode()) || !StringUtils.isEmpty(req.getCustName()) ||
                !StringUtils.isEmpty(req.getCustAddress()) || !StringUtils.isEmpty(req.getCustPhone()) ||
                !StringUtils.isEmpty(req.getIndustryType()) ) {
            LambdaQueryWrapper<Consumer> queryWrapper = new LambdaQueryWrapper();
            if (!StringUtils.isEmpty(req.getSubsCode())) {
                queryWrapper.like(Consumer::getSubsCode, req.getSubsCode());
            }
            if (!StringUtils.isEmpty(req.getCustName())) {
                queryWrapper.like(Consumer::getCustName, req.getCustName());
            }
            if (!StringUtils.isEmpty(req.getCustAddress())) {
                queryWrapper.like(Consumer::getCustAddress, req.getCustAddress());
            }
            if (!StringUtils.isEmpty(req.getCustPhone())) {
                queryWrapper.like(Consumer::getCustPhone, req.getCustPhone());
            }
            if (!StringUtils.isEmpty(req.getIndustryType())) {
                queryWrapper.eq(Consumer::getIndustryType, req.getIndustryType());
            }
            if (!StringUtils.isEmpty(req.getOrgCode())) {
                queryWrapper.eq(Consumer::getOrgCode, req.getOrgCode());
            }
            if (!StringUtils.isEmpty(req.getCustomerAddress())) {
                queryWrapper.like(Consumer::getCustomerAddress, req.getCustomerAddress());
            }
            queryWrapper.eq(Consumer::getSpId, spId);
            consumerIds = consumerService.list(queryWrapper).stream().map(Consumer::getId).collect(Collectors.toList());
            if (consumerIds.isEmpty()) {
                return new PageUtil(req.getPage(), req.getPageSize(), 0, resultList, pageColumns);
            }
        }
        //根据条件查询复位记录表
        LambdaQueryWrapper<Maintainlog> queryWrapper = new LambdaQueryWrapper();
        if (!consumerIds.isEmpty()) {
            queryWrapper.in(Maintainlog::getConsumerId,consumerIds);
        }
        if (!StringUtils.isEmpty(req.getTimeStart())) {
            queryWrapper.ge(Maintainlog::getTime, req.getTimeStart());
        }
        if (!StringUtils.isEmpty(req.getTimeEnd())) {
            queryWrapper.le(Maintainlog::getTime, req.getTimeEnd());
        }
        if (!StringUtils.isEmpty(req.getUserName())) {
            queryWrapper.like(Maintainlog::getPersonName, req.getUserName());
        }
        queryWrapper.eq(!StringUtils.isEmpty(path), Maintainlog::getPath, path).orderByDesc(Maintainlog::getTime);

        //数据权限
        List<Integer> permissionConsumerIds = userPermissionService.getDepartConsumerIds(spId, ApplicationUtils.getUserId());
        if( null!=permissionConsumerIds && !permissionConsumerIds.isEmpty()){
            queryWrapper.in(Maintainlog::getConsumerId,permissionConsumerIds);
        }

        Page pageHelper = PageHelper.startPage(req.getPage(), req.getPageSize());
        List<Maintainlog> list = maintainlogMapper.selectList(queryWrapper);
        //收集复位记录表的设备号
        if (!list.isEmpty()) {
            //查询所属部门
            LambdaQueryWrapper<Department> departmentWrapper = new LambdaQueryWrapper();
            departmentWrapper.in(Department::getId, list.stream().map(Maintainlog::getDepartmentId).collect(Collectors.toList()));
            List<Department> departmentList = departmentService.list(departmentWrapper);
            Map<Integer, Department> departmentMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(departmentList)) {
                departmentMap = departmentList.stream().collect(Collectors.toMap(Department::getId, Department -> Department, (a1, a2) -> a1));
            }
            //查询客户信息
            LambdaQueryWrapper<Consumer> consumerQueryWrapper = new LambdaQueryWrapper<>();
            consumerQueryWrapper.eq(Consumer::getSpId, spId).in(Consumer::getId, list.stream().map(Maintainlog::getConsumerId).collect(Collectors.toList()));
            List<Consumer> consumerList = consumerService.list(consumerQueryWrapper);
            Map<Integer, Consumer> consumerMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(consumerList)) {
                consumerMap = consumerList.stream().collect(Collectors.toMap(Consumer::getId, Consumer -> Consumer, (a1, a2) -> a1));
            }

            List<String> spIds = new ArrayList<>();
            spIds.add(spId);
            //查询组织架构名称
            List<CompanyResponse> companyNameList = companyService.queryCompanyNameList(spIds);
            Map<String, String> companyNameMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(companyNameList)) {
                companyNameMap = companyNameList.stream().collect(Collectors.toMap(CompanyResponse::getSpId, CompanyResponse::getName));
            }
            //批量查询字典
            List<DictionaryItemRespDTO> orgMapSubsCodeList = holder.getDictionaryByKey(ORG_MAP_SUBSCODE);
            Map<String, String> orgSubsCodeMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(orgMapSubsCodeList)) {
                orgSubsCodeMap = orgMapSubsCodeList.stream().collect(Collectors.toMap(DictionaryItemRespDTO::getDescription, DictionaryItemRespDTO::getCompanyName));
            }
            List<DictionaryItemRespDTO> industryTypeCodeList = holder.getDictionaryByKey(Constants.INDUSTRY_TYPE_CODE);

            //查询
            for (Maintainlog maintainlog : list) {
                MaintainLogResponse res = new MaintainLogResponse();
                BeanUtils.copyProperties(maintainlog, res);
                //填写人
                res.setUserName(maintainlog.getPersonName());
                if (departmentMap.containsKey(maintainlog.getDepartmentId())) {
                    Department department = departmentMap.get(maintainlog.getDepartmentId());
                    res.setDepartment(department.getName());
                }
                if (consumerMap.containsKey(res.getConsumerId())) {
                    Consumer consumer = consumerMap.get(res.getConsumerId());
                    res.setSubsCode(consumer.getSubsCode());
                    res.setName(consumer.getName());
                    res.setConsumerType(consumer.getConsumerType());
                    res.setIndustryType(consumer.getIndustryType());
                    res.setCustName(consumer.getCustName());
                    res.setCustAddress(consumer.getCustAddress());
                    res.setCustPhone(consumer.getCustPhone());
                    //行业类型
                    if (!StringUtils.isEmpty(res.getIndustryType())) {
                        res.setIndustryTypeName(getName(industryTypeCodeList,res.getIndustryType()));
                    }
                    if (org.apache.commons.lang3.StringUtils.isNotEmpty(consumer.getOrgCode()) && orgSubsCodeMap.containsKey(consumer.getOrgCode())) {
                        res.setCompanyName(orgSubsCodeMap.get(consumer.getOrgCode()));
                    } else {
                        if (companyNameMap.containsKey(consumer.getSpId())) {
                            res.setCompanyName(companyNameMap.get(consumer.getSpId()));
                        }
                    }
                }
                res.setLatestTime(maintainlog.getTime());
                res.setId(maintainlog.getId().longValue());
                resultList.add(res);
            }
        }
        if (!StringUtils.isEmpty(req.getConsumerId()))
            resultList = resultList.stream().filter(maintainLogResponse -> {
                return maintainLogResponse.getConsumerId().equals(req.getConsumerId());
            }).collect(Collectors.toList());
        commonService.loadFieldAndPackaging(resultList, MaintainLogResponse.class, resultList.stream().map(MaintainLogResponse::getConsumerId).collect(Collectors.toList()), null, null, spId, PageListCode.MAINTAIN_RECORD.getCode());
        log.info("maintainList-resultList:{}", com.alibaba.fastjson.JSONObject.toJSONString(resultList));
        PageUtil pageInfo = new PageUtil(req.getPage(), req.getPageSize(), pageHelper.getTotal(), resultList, pageColumns);
        return pageInfo;
    }

    private String getName(List<DictionaryItemRespDTO> list, String  value) {
        if( !CollectionUtils.isEmpty(list)){
            List<DictionaryItemRespDTO> respDTOS = list.stream()
                    .filter(dict -> dict.getValue().equals(value)).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(respDTOS)){
                return respDTOS.get(0).getName();
            }
        }
        return null;
    }

    @Override
    public void add(MaintainLogAddRequest req) {
        String spId = ApplicationUtils.getWorkingSpId();
        String path = departmentService.getPath(spId);

        Consumer consumer = consumerService.getById(req.getConsumerId());
        if (consumer != null && !consumer.getIsDeleted()) {
            Maintainlog log = new Maintainlog();
            log.setTime(new Date());
            log.setUserId(0);
            log.setConsumerId(consumer.getId());
            log.setDepartmentId(consumer.getDepartmentId());
            log.setMessage(req.getMessage());
            log.setPath(path);
            log.setPersonCode(ApplicationUtils.getWorkingUser().getUsername());
            log.setPersonName(ApplicationUtils.getWorkingUser().getName());
            this.save(log);
        }
    }
}
